﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Web.UI;
using Microsoft.Office.Server.UserProfiles;

namespace Trig_AMJ_IT_Customforms
{
    class Trig_WF :ExceptionHandler 
    {
        string AssignedToUser = string.Empty;
        SPFieldUserValue ofldWFUser = null;
        Demand_Voucher_FormClass dmdVocherClass = new Demand_Voucher_FormClass();
        string WorkflowConfigList = "Workflow Configuration List";
        string currentUser = SPContext.Current.Web.CurrentUser.LoginName;
        ExceptionHandler exceptionHandler = new ExceptionHandler();
        /// <summary>
        /// create task to users based on the task type which are configured in the workflow configuration list
        /// </summary>
        /// <param name="FormsWebName"></param>
        /// <param name="FormsLibraryorList"></param>
        /// <param name="TaskList"></param>
        /// <param name="wfConfigurationList"></param>
        /// <param name="peForwardUsers"></param>
        /// <param name="WFCurrentOrder"></param>
        /// <param name="UPAttributeName"></param>
        /// <param name="internalStaff"></param>
        /// <param name="sendbackuser"></param>
        /// <param name="taskType"></param>
        /// <param name="referenceNumber"></param>
        /// <param name="ECListName"></param>
        /// <param name="ECUserFieldName"></param>
        /// <param name="ECMatchField"></param>
        /// <param name="ECUPMatchFieldText"></param>

        public void createTask(SPWeb FormsWebName, SPList FormsLibraryorList, SPList TaskList, string wfConfigurationList, PeopleEditor peForwardUsers, int WFCurrentOrder,
            string UPAttributeName, bool internalStaff, bool sendbackuser, string taskType, string referenceNumber, string ECListName, string ECUserFieldName, string ECMatchField, string ECUPMatchFieldText)
        {
            try
            {
                SPList wfConfigList = FormsWebName.Lists.TryGetList(wfConfigurationList);
                if (TaskList != null && wfConfigList != null)
                {
                    SPQuery oqry = new SPQuery();
                    oqry.Query = "<Where><And><Eq><FieldRef Name='Order0' /><Value Type='Number'>" + WFCurrentOrder + "</Value></Eq><Eq><FieldRef Name='Doctype' /><Value Type='Lookup'>" + FormsLibraryorList.Title + "</Value></Eq></And></Where>";
                    SPListItemCollection oitmcoll = wfConfigList.GetItems(oqry);
                    if (oitmcoll.Count > 0)
                    {
                        SPListItem UserItem = oitmcoll[0];
                        AssignedToUser = Convert.ToString(UserItem["Send_x0020_to_x0020_Users"]);
                        if (!string.IsNullOrEmpty(AssignedToUser))
                        {
                            ofldWFUser = new SPFieldUserValue(FormsWebName, Convert.ToString(UserItem["Send_x0020_to_x0020_Users"]));
                        }
                        if (!string.IsNullOrEmpty(AssignedToUser) && taskType == "Static")
                        {
                            if (ofldWFUser != null)
                            {
                                createTasktoUsers(FormsWebName, FormsLibraryorList, TaskList, ofldWFUser, referenceNumber, WFCurrentOrder, taskType,false);
                            }
                        }
                        else if (!string.IsNullOrEmpty(AssignedToUser) && taskType == "Dynamic")
                        {
                            createTasktoDynamicUsers(FormsWebName, FormsLibraryorList, TaskList, ofldWFUser, peForwardUsers, referenceNumber, WFCurrentOrder, taskType, internalStaff, sendbackuser);
                        }
                        else if (taskType == "UP Attribute")
                        {
                            SPFieldLookupValue ofldUPAttributeVal = new SPFieldLookupValue(UPAttributeName);
                            if (ofldUPAttributeVal != null)
                            {
                                createTasktoUPAttribute(FormsWebName, FormsLibraryorList, TaskList, currentUser, ofldUPAttributeVal.LookupValue, referenceNumber, WFCurrentOrder, taskType);
                            }
                        }
                        else if (taskType == "EC (Externally Configured)")
                        {
                            createTasktoExtranallyConfigured(FormsWebName, FormsLibraryorList, TaskList, currentUser, referenceNumber, WFCurrentOrder, taskType, ECListName, ECUserFieldName, ECMatchField, ECUPMatchFieldText);
                        }
                    }
                    else
                    {
                        GenerateExceptionLog("Trig_AMJ_IT_Forms::Trig_WF.cs::createTask Workflow does not configured or Workflow steps are completed for " + FormsLibraryorList.Title + ",Kindly check the the workflow configuration for " + FormsLibraryorList.Title + ".", "createTask", "Trig_WF.cs");
                    }
                }
                else
                {
                    GenerateExceptionLog("Trig_AMJ_IT_Forms::Trig_WF.cs::createTask", "List does not exist", "Task list or WF config list does not exist");
                }
            }
            catch (Exception ex)
            {
                GenerateExceptionLog("Trig_AMJ_IT_Forms::Trig_WF.cs::createTask", "Exception in catch block", ex.Message);
            }
        }

        /// <summary>
        /// Create task to users when the task type is static
        /// </summary>
        /// <param name="FormsWeb"></param>
        /// <param name="FormsList"></param>
        /// <param name="TasksList"></param>
        /// <param name="userName"></param>
        /// <param name="referenceNumber"></param>
        /// <param name="WFCurrentOrder"></param>
        public void createTasktoUsers(SPWeb FormsWeb, SPList FormsList, SPList TasksList, SPFieldUserValue userName, string referenceNumber, int WFCurrentOrder, string taskType, bool AssignTosubmitUser)
        {
            try
            {
                if (TasksList != null && FormsList != null)
                {
                    SPListItem taskItem = TasksList.Items.Add();
                    taskItem["Title"] = "FirstTask";
                    taskItem["AssignedTo"] = userName;
                    taskItem["Reference_x0020_Number"] = referenceNumber;
                    taskItem["ListID"] = FormsList.ID;
                    taskItem["WFCurrentOrder"] = WFCurrentOrder;
                    taskItem["WFTaskType"] = taskType;
                    FormsWeb.AllowUnsafeUpdates = true;
                    taskItem.Update();
                    FormsWeb.AllowUnsafeUpdates = false;
                    //if (WFCurrentOrder != 1 || WFCurrentOrder == 1)
                    if (WFCurrentOrder != 1 &&  !AssignTosubmitUser)
                    {
                        dmdVocherClass.UpdateFormStatus(FormsWeb, WorkflowConfigList, FormsList.Title, referenceNumber, WFCurrentOrder, false);
                    }
                }
            }
            catch (Exception ex)
            {
                GenerateExceptionLog("Trig_AMJ_IT_Forms::Trig_WF.cs::createTasktoUsers", ex.Message, "Exception in catch block");
            }
        }

        /// <summary>
        /// Create task to users when the task type is Dynamic
        /// </summary>
        /// <param name="FormsWeb"></param>
        /// <param name="FormsList"></param>
        /// <param name="TasksList"></param>
        /// <param name="userName"></param>
        /// <param name="peForwardUsers"></param>
        /// <param name="referenceNumber"></param>
        /// <param name="WFCurrentOrder"></param>
        /// <param name="InternallyForward"></param>
        /// <param name="sendbackUsers"></param>
        public void createTasktoDynamicUsers(SPWeb FormsWeb, SPList FormsList, SPList TasksList, SPFieldUserValue userName, PeopleEditor peForwardUsers, string referenceNumber, int WFCurrentOrder, string taskType, bool InternallyForward, bool sendbackUsers)
        {
            try
            {
                if (InternallyForward)
                {
                    foreach (PickerEntity entity in peForwardUsers.ResolvedEntities)
                    {
                        if (entity.IsResolved == true)
                        {
                            SPUser user = FormsWeb.EnsureUser(entity.Key);
                            userName = new SPFieldUserValue(FormsWeb, user.ID, user.Name);
                            createTasktoUsers(FormsWeb, FormsList, TasksList, userName, referenceNumber, WFCurrentOrder, taskType,false);
                        }
                    }
                }
                else if (sendbackUsers)
                {
                    userName = getSendBackUserfNametoAssignLabelText(FormsWeb, TasksList.Title, referenceNumber);
                    createTasktoUsers(FormsWeb, FormsList, TasksList, userName, referenceNumber, WFCurrentOrder, taskType,false);

                }
                else
                {
                    if (userName != null)
                    {
                        createTasktoUsers(FormsWeb, FormsList, TasksList, userName, referenceNumber, WFCurrentOrder, taskType,false);
                    }
                }
            }
            catch (Exception ex)
            {
                GenerateExceptionLog("Trig_AMJ_IT_Forms::Trig_WF.cs::createTasktoDynamicUsers", ex.Message, "Exception in catch block");

            }
        }


        /// <summary>
        /// create task based on the user profile attribute
        /// </summary>
        public void createTasktoUPAttribute(SPWeb FormsWeb, SPList FormsList, SPList TasksList, string CurrentUserName, string UPAttributeName, string referenceNumber, int WFCurrentOrder, string taskType)
        {
            try
            {
                var userProfileManager = new UserProfileManager();
                if (userProfileManager.UserExists(CurrentUserName))
                {
                    var userProfile = userProfileManager.GetUserProfile(CurrentUserName);
                    if (userProfile != null && userProfile.Properties.GetPropertyByName(UPAttributeName) != null)
                    {
                        FormsWeb.AllowUnsafeUpdates = true;
                        if (userProfile[UPAttributeName].Value != null)
                        {
                            string UPName = Convert.ToString(userProfile[UPAttributeName]);
                            if (!string.IsNullOrEmpty(UPName))
                            {
                                SPUser UPUserName = FormsWeb.EnsureUser(UPName);
                                SPFieldUserValue userValue = new SPFieldUserValue(FormsWeb, UPUserName.ID, UPUserName.Name);
                                FormsWeb.AllowUnsafeUpdates = false;
                                createTasktoUsers(FormsWeb, FormsList, TasksList, userValue, referenceNumber, WFCurrentOrder, taskType,false);
                            }
                            else
                            {
                                GenerateExceptionLog("Trig_AMJ_IT_Forms::Trig_WF.cs::createTasktoUPAttribute", "UserProfile Property value is empty", "Please set value to " + UPName + " property");
                            }
                        }
                        else
                        {
                            GenerateExceptionLog("Trig_AMJ_IT_Forms::Trig_WF.cs::createTasktoUPAttribute", "UserProfile Property value is null", "Please set value to the " + UPAttributeName + " property");
                        }
                    }
                    else
                    {
                        GenerateExceptionLog("Trig_AMJ_IT_Forms::Trig_WF.cs::createTasktoUPAttribute", "UserProfile Property does not exist", UPAttributeName + " Property does not exist. Create and set value to the property");
                    }
                }
                else
                {
                    GenerateExceptionLog("Trig_AMJ_IT_Forms::Trig_WF.cs::createTasktoUPAttribute", "UserProfile does not exist", "UserProfile does not exist for the" + CurrentUserName + " user");
                }
            }
            catch (Exception ex)
            {
                GenerateExceptionLog("Trig_AMJ_IT_Forms::Trig_WF.cs::createTasktoUPAttribute", "Exception in catch block", ex.Message);
            }
        }


        /// <summary>
        /// Create a task to users based on condition which is configured in Workflow configuration List
        /// </summary>
        /// <param name="FormsWeb"></param>
        /// <param name="FormsList"></param>
        /// <param name="TasksList"></param>
        /// <param name="referenceNumber"></param>
        /// <param name="WFCurrentOrder"></param>
        /// <param name="ECListName"></param>
        /// <param name="ECUserFieldName"></param>
        /// <param name="ECMatchField"></param>
        /// <param name="ECUPMatchFieldText"></param>
        public void createTasktoExtranallyConfigured(SPWeb FormsWeb, SPList FormsList, SPList TasksList, string CurrentUserName, string referenceNumber, int WFCurrentOrder, string taskType, string ECListName, string ECUserFieldName, string ECMatchField, string ECUPMatchFieldText)
        {
            try
            {
                if (!string.IsNullOrEmpty(ECListName))
                {
                    SPList ECList = FormsWeb.Lists.TryGetList(ECListName);
                    if (ECList != null)
                    {
                        if (!string.IsNullOrEmpty(ECUserFieldName) && !string.IsNullOrEmpty(ECMatchField) && !string.IsNullOrEmpty(ECUPMatchFieldText))
                        {
                            FormsWeb.AllowUnsafeUpdates = true;
                            if (ECList.Fields.ContainsField(ECMatchField) && ECList.Fields.ContainsField(ECUserFieldName))
                            {
                                SPField SPECMatchField = ECList.Fields[ECMatchField];
                                FormsWeb.AllowUnsafeUpdates = true;
                                var userProfileManager = new UserProfileManager();
                                if (userProfileManager.UserExists(CurrentUserName))
                                {
                                    var userProfile = userProfileManager.GetUserProfile(CurrentUserName);
                                    if (userProfile != null && userProfile.Properties.GetPropertyByName(ECUPMatchFieldText) != null)
                                    {
                                        if (userProfile[ECUPMatchFieldText] != null)
                                        {
                                            string ECUPValue = Convert.ToString(userProfile[ECUPMatchFieldText]);// if (userProfile.Properties.GetPropertyByName(ECUPMatchFieldText) == PropertyDataType.String)
                                            SPQuery matchQry = new SPQuery();
                                            matchQry.Query = "<Where><Eq><FieldRef Name='" + SPECMatchField.InternalName + "' /><Value Type='" + SPECMatchField.Type + "'>" + ECUPValue + "</Value></Eq></Where>";
                                            if (ECList.GetItems(matchQry).Count > 0)
                                            {
                                                string userName = Convert.ToString(ECList.GetItems(matchQry)[0][ECUserFieldName]);
                                                if (!string.IsNullOrEmpty(userName))
                                                {
                                                    SPFieldUserValue userValue = new SPFieldUserValue(FormsWeb, ECList.GetItems(matchQry)[0][ECUserFieldName].ToString());
                                                    FormsWeb.AllowUnsafeUpdates = false;
                                                    createTasktoUsers(FormsWeb, FormsList, TasksList, userValue, referenceNumber, WFCurrentOrder, taskType,false);
                                                }
                                                else
                                                {
                                                    GenerateExceptionLog("Trig_AMJ_IT_Forms::Trig_WF.cs::createTasktoExtranallyConfigured", "User not found", "Please configure the User in the " + ECUserFieldName + " column");
                                                }
                                            }
                                            else
                                            {
                                                GenerateExceptionLog("Trig_AMJ_IT_Forms::Trig_WF.cs::createTasktoExtranallyConfigured", "Match Query count is null", "Check the Query values");
                                            }
                                        }
                                        else
                                        {
                                            GenerateExceptionLog("Trig_AMJ_IT_Forms::Trig_WF.cs::createTasktoExtranallyConfigured", "UserProfile Property value is null", ECUPMatchFieldText + " Propery values is null or empty for " + currentUser);
                                        }
                                    }
                                    else
                                    {
                                        GenerateExceptionLog("Trig_AMJ_IT_Forms::Trig_WF.cs::createTasktoExtranallyConfigured", "UserProfile Property does not exist", ECUPMatchFieldText + " Propery does not exist for " + currentUser);
                                    }
                                }
                                else
                                {
                                    GenerateExceptionLog("Trig_AMJ_IT_Forms::Trig_WF.cs::createTasktoExtranallyConfigured", "User profile not found", currentUser + " user does not exist in the UserProfile");
                                }
                            }
                            else
                            {
                                string msg = ECMatchField + " or " + ECUserFieldName + " does not exist in " + ECListName + " List";
                                GenerateExceptionLog("Trig_AMJ_IT_Forms::Trig_WF.cs::createTasktoExtranallyConfigured", "Field does not exist", msg);
                            }
                            FormsWeb.AllowUnsafeUpdates = false;
                        }
                    }
                    else
                    {
                        GenerateExceptionLog("Trig_AMJ_IT_Forms::Trig_WF.cs::createTasktoExtranallyConfigured", "List does not exist", ECListName + " List does not exist");
                    }
                }
            }
            catch (Exception ex)
            {
                GenerateExceptionLog("Trig_AMJ_IT_Forms::Trig_WF.cs::createTasktoExtranallyConfigured", "Catch Block Exception", ex.Message);
            }
        }

        /// <summary>
        /// Reject the Workflow
        /// </summary>
        /// <param name="FormsWeb"></param>
        /// <param name="TasksitemId"></param>
        /// <param name="TasksList"></param>
        public void RejectTask(string FormsUrl, string TasksitemId, string TaskListName, string FormsList, string referenceNumber)
        {
            try
            {
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    using (SPSite frmSite = new SPSite(FormsUrl))
                    {
                        using (SPWeb FormsWeb = frmSite.OpenWeb())
                        {
                            SPList TasksList = FormsWeb.Lists.TryGetList(TaskListName);
                            if (TasksList != null)
                            {
                                SPListItem taskItem = TasksList.GetItemById(Convert.ToInt32(TasksitemId));
                                taskItem["Status"] = "Completed";
                                taskItem["OutCome"] = "Rejected";
                                FormsWeb.AllowUnsafeUpdates = true;
                                taskItem.Update();
                                FormsWeb.AllowUnsafeUpdates = false;
                                dmdVocherClass.UpdateFormStatus(FormsWeb, WorkflowConfigList, FormsList, referenceNumber, Convert.ToInt32(taskItem["WFCurrentOrder"]), true);
                            }
                            else
                            {
                                GenerateExceptionLog("Trig_AMJ_IT_Forms::Trig_WF.cs::RejectTask", "Tasks list does not exist", TaskListName + " List does not exist");
                            }
                        }
                    }
                });
            }
            catch (Exception ex)
            {
                GenerateExceptionLog("Trig_AMJ_IT_Forms::Trig_WF.cs::RejectTask", "Catch Block Exception", ex.Message);
            }
        }

        /// <summary>
        /// SEnd back the WF to user
        /// </summary>
        /// <param name="siteUrl"></param>
        /// <param name="taskList"></param>
        /// <param name="taskItemID"></param>
        /// <param name="RefNO"></param>
        /// <returns></returns>

        public SPFieldUserValue getSendBackUserfNametoAssignLabelText(SPWeb frmWeb, string taskList, string RefNO)
        {
            SPFieldUserValue ofldval = null;
            try
            {
                SPQuery oqy = new SPQuery();
                oqy.Query = "<Where><And><Eq><FieldRef Name='Reference_x0020_Number' /><Value Type='Text'>" + RefNO + "</Value></Eq><Eq><FieldRef Name='Status' /><Value Type='Choice'>Completed</Value></Eq></And></Where><OrderBy><FieldRef Name='ID' Ascending='False' /></OrderBy>";
                if (frmWeb.Lists.TryGetList(taskList) != null)
                {
                    if (frmWeb.Lists.TryGetList(taskList).GetItems(oqy).Count > 0)
                    {
                        SPListItem oitm = frmWeb.Lists.TryGetList(taskList).GetItems(oqy)[0];
                        ofldval = new SPFieldUserValue(frmWeb, Convert.ToString(oitm["AssignedTo"]));
                    }

                }

            }
            catch (Exception ex)
            {
                GenerateExceptionLog("Trig_AMJ_IT_Forms::Trig_WF::getSendBackUserfNametoAssignLabelText()", "Exception in catch block", ex.Message);
            }

            return ofldval;
        }

    }
}
